from decimal import Decimal
from typing import Optional, Union
from datetime import datetime
from pydantic import BaseModel, validator, constr, ConfigDict


class CoreModel(BaseModel):
    """
    Any common logic to be shared by all models goes here
    """
    pass


class DateTimeModelMixin(BaseModel):
    created_at: Optional[datetime]
    updated_at: Optional[datetime]




class IDModelMixin(BaseModel):
    model_config = ConfigDict(
        from_attributes=True
    )
    id: int


class UserBase(CoreModel):
    model_config = ConfigDict(
        from_attributes=True
    )
    username: str
    phone: str


class UserCreate(UserBase):
    model_config = ConfigDict(
        from_attributes=True
    )
    password: str


class UserRegister(BaseModel):
    model_config = ConfigDict(
        from_attributes=True
    )
    username: str
    password: str
    phone: str
    code: str


class UserPasswordUpdate(CoreModel):
    model_config = ConfigDict(
        from_attributes=True
    )
    """
    Users can change their password
    """
    password: constr(min_length=7, max_length=100)
    salt: str



class UserInDB(DateTimeModelMixin, UserBase):
    model_config = ConfigDict(
        from_attributes=True
    )
    """
    Add in id, created_at, updated_at, and user's password and salt
    """
    password: constr(min_length=7, max_length=100)
    salt: str


class UserPublic(DateTimeModelMixin, UserBase):
    model_config = ConfigDict(
        from_attributes=True
    )


class User(UserBase):
    model_config = ConfigDict(
        from_attributes=True
    )
    id: int
    disabled: int
    is_superuser: int
    discount: float
    openid: Union[str, None]
    gift: Decimal




class UserOperationLog(DateTimeModelMixin):
    model_config = ConfigDict(
        from_attributes=True
    )
    uid: str
    path: str
    method: str
    ip: str
    input: str




class VipRecordBase(DateTimeModelMixin):
    model_config = ConfigDict(
        from_attributes=True
    )
    pid: int
    uid: str
    status: Union[int, None] = None
    order_sn: str
    amount: float
    length: int







class RolesInDB(DateTimeModelMixin):
    model_config = ConfigDict(
        from_attributes=True
    )
    order_sn: str
    amount: float
    length: int


